# 标准库导入
import random

# Django框架导入
from django.conf import settings
from django.db import models
from django.contrib.auth.models import AbstractUser, Group, Permission
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType

class Company(models.Model):
    '''定义省公司部门及地市级的管理域'''
    id = models.SmallAutoField(primary_key=True)
    company = models.CharField(max_length=50, verbose_name='地市名称')
    is_deleted = models.BooleanField(default=False, verbose_name='是否删除')

    def __str__(self):
        return self.company

    class Meta:
        verbose_name = '所属公司'
        verbose_name_plural = '所属公司'
        ordering = ['-id']


class Department(models.Model):
    '''定义部门及县区级的管理域'''
    id = models.SmallAutoField(primary_key=True)
    department = models.CharField(max_length=30, verbose_name='所属县区')
    company = models.ForeignKey(Company, on_delete=models.PROTECT, null=False, blank=False, verbose_name='所属地市')
    creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=True, blank=True, related_name='created_departments', verbose_name='创建人')
    is_deleted = models.BooleanField(default=False, verbose_name='是否删除')
    def __str__(self):
        return self.department

    class Meta:
        verbose_name = '所属县区'
        verbose_name_plural = '所属县区'
        ordering = ['-id']


class CustomUser(AbstractUser):
    '''定义用户扩展信息，用于权限分配和管理域的控制'''
    realname = models.CharField(max_length=30, null=True, blank=True, verbose_name='姓名')
    phone_number = models.CharField(max_length=11, null=True, blank=True, verbose_name='手机号')
    wechat = models.CharField(max_length=30, null=True, blank=True, verbose_name='微信号')
    is_manager = models.BooleanField(default=False, verbose_name='管理员')
    is_broad = models.BooleanField(default=False, verbose_name='管理全域')
    is_approver = models.BooleanField(default=False, verbose_name='有审批权')
    is_deviceoperator = models.BooleanField(default=False, verbose_name='设备权')
    is_inventoryoperator = models.BooleanField(default=False, verbose_name='物料操权')
    can_add_device = models.BooleanField(default=True, verbose_name='可添加设备')
    department = models.ForeignKey(Department, null=True, blank=True, on_delete=models.PROTECT, verbose_name='所属县区')
    company = models.ForeignKey(Company, null=True, blank=True, on_delete=models.PROTECT, verbose_name='所属地市')
    role = models.CharField(max_length=20, null=True, blank=True, verbose_name='角色')  # 备用字段



    def __str__(self):
        return self.username
    class Meta:
        verbose_name = '增补用户信息'
        verbose_name_plural = '增补用户信息'


class Factory(models.Model):
    '''定义设备的生产厂家，供后续设备的添加使用'''
    id = models.SmallAutoField(primary_key=True, verbose_name='厂家编号')
    factory = models.CharField(max_length=30, verbose_name='厂家名称')
    company = models.ForeignKey(Company, on_delete=models.PROTECT, verbose_name='所属地市')
    is_deleted = models.BooleanField(default=False, verbose_name='是否删除')
    def __str__(self):
        return self.factory

    class Meta:
        verbose_name = '设备厂家清单'
        verbose_name_plural = '设备厂家清单'
        ordering = ['-id']


class Technology(models.Model):
    '''定义政企接入设备的技术类别，供后续设备的添加使用'''
    id = models.SmallAutoField(primary_key=True, verbose_name='技术编号')
    technology = models.CharField(max_length=30, verbose_name='技术类别')
    company = models.ForeignKey(Company, on_delete=models.PROTECT, verbose_name='所属地市')
    is_deleted = models.BooleanField(default=False, verbose_name='是否删除')
    def __str__(self):
        return self.technology

    class Meta:
        verbose_name = '设备技术类别'
        verbose_name_plural = '设备技术类别'
        ordering = ['-id']


class Place(models.Model):
    '''定义政企接入设备的存放位置，损毁代表回收失败'''
    id = models.SmallAutoField(primary_key=True, verbose_name='位置编号')
    place = models.CharField(max_length=30, verbose_name='存放位置')
    department = models.ForeignKey(Department, on_delete=models.PROTECT, verbose_name='所属县区')
    company = models.ForeignKey(Company, on_delete=models.PROTECT, verbose_name='所属地市')
    attribute = models.SmallIntegerField(choices=[(1, '库存'), (2, '专线用户'), (3, '电路用户'), (4, '损毁'), (5, '核销')], verbose_name='使用属性')
    is_deleted = models.BooleanField(default=False, verbose_name='是否删除')
    def __str__(self):
        return self.place

    class Meta:
        verbose_name = '设备存放位置'
        verbose_name_plural = '设备存放位置'
        ordering = ['-id']


def generate_default_number(): 
    '''生成唯一的七位设备管理编号字符串'''
    while True:
        number = str(random.randint(1000000, 9999999))
        if not Device.objects.filter(number=number).exists():
            return number


class Device(models.Model): 
    '''政企接入设备的分布信息和使用、库存信息'''
    id = models.AutoField(primary_key=True)
    number = models.IntegerField(default=generate_default_number, verbose_name='管理编号')
    model = models.CharField(max_length=30, null=True, blank=True, verbose_name='规格型号')
    factory = models.ForeignKey(Factory, on_delete=models.PROTECT, verbose_name='生产厂家')
    technology = models.ForeignKey(Technology, on_delete=models.PROTECT, verbose_name='技术类别')
    place = models.ForeignKey(Place, on_delete=models.PROTECT, verbose_name='存放位置')
    state = models.SmallIntegerField(choices=[(1, '正常'), (2, '故障')], default=1, verbose_name='故障状态')
    mac = models.CharField(max_length=30, null=True, blank=True, verbose_name='MAC地址')
    summary = models.CharField(max_length=200, null=True, blank=True, verbose_name='简要说明')
    cust_code = models.CharField(max_length=50, null=True, blank=True, verbose_name='电路代号')                                 
    cust_name = models.CharField(max_length=100, null=True, blank=True, verbose_name='客户名称')
    create_date = models.DateField(verbose_name='录入日期')
    create_user = models.ForeignKey(CustomUser, null=True, blank=True, on_delete=models.PROTECT, verbose_name='录入人员')
    update_date = models.DateField(null=True, blank=True, verbose_name='更新日期')
    project = models.CharField(max_length=50, null=True, blank=True, verbose_name='来源项目')
    attribute = models.SmallIntegerField(choices=[(1, '库存'), (2, '专线用户'), (3, '电路用户'), (4, '损毁'), (5, '核销')], default=1, verbose_name='使用属性')
    department = models.ForeignKey(Department, on_delete=models.PROTECT, verbose_name='县区名称')
    company = models.ForeignKey(Company, on_delete=models.PROTECT, verbose_name='所属地市')
    is_deleted = models.BooleanField(default=False, verbose_name='是否删除')

    def __str__(self):
        return str(self.number)
    
    class Meta:
        verbose_name = '设备当前信息'
        verbose_name_plural = '设备当前信息'
        ordering = ['-id']
        indexes = [
            models.Index(fields=['factory']),
            models.Index(fields=['technology']),
            models.Index(fields=['place']),
            models.Index(fields=['cust_name']),
            models.Index(fields=['attribute']),
            models.Index(fields=['department']), 
            models.Index(fields=['company'])
        ]


class DeviceHistory(models.Model): 
    '''政企接入设备的变更记录'''
    id = models.AutoField(primary_key=True)
    STATUS_CHOICES = (
    ('pending', '待审批'),
    ('approved', '批准'),
    ('rejected', '拒绝'),
    )
    number = models.IntegerField(verbose_name='管理编号')
    cust_code = models.CharField(max_length=50, null=True, blank=True, verbose_name='电路代号')                                 
    cust_name = models.CharField(max_length=100, null=True, blank=True, verbose_name='客户名称')
    placebefore = models.ForeignKey(Place, on_delete=models.PROTECT, related_name='device_histories_as_placebefore', verbose_name='原位置')
    placenow = models.ForeignKey(Place, on_delete=models.PROTECT, related_name='device_histories_as_placenow', verbose_name='现位置')
    statebefore = models.SmallIntegerField(choices=[(1, '正常'), (2, '故障')], verbose_name='原故障状态')
    statenow = models.SmallIntegerField(choices=[(1, '正常'), (2, '故障')], verbose_name='现故障状态')
    reason = models.CharField(max_length=100, verbose_name='变更原因')
    create_date = models.DateField(verbose_name='申请日期')
    approvalstatus = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending', verbose_name='审批状态')
    operator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, related_name='operated_device_histories', verbose_name='操作人')
    approver = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.PROTECT, related_name='approved_device_histories', verbose_name='审批人')
    approval_date = models.DateTimeField(null=True, blank=True, verbose_name='审批日期')
    approval_opinion = models.CharField(max_length=100, default='同意', null=True, blank=True, verbose_name='审批意见')
    departmentbefore = models.ForeignKey(Department, on_delete=models.PROTECT, related_name='device_histories_as_departmentbefore', verbose_name='原县区')
    departmentnow = models.ForeignKey(Department, on_delete=models.PROTECT, related_name='device_histories_as_departmentnow', verbose_name='现县区')
    company = models.ForeignKey(Company, on_delete=models.PROTECT, verbose_name='所属地市')
    def __str__(self):
        return str(self.number)
    class Meta:
        verbose_name = '设备变更记录'
        verbose_name_plural = '设备变更记录'
        ordering = ['-id']
        indexes = [
            models.Index(fields=['placebefore']),
            models.Index(fields=['placenow']),
            models.Index(fields=['departmentbefore']),
            models.Index(fields=['departmentnow']),
            models.Index(fields=['company']),
            models.Index(fields=['operator']),
            models.Index(fields=['approver']),
            models.Index(fields=['approvalstatus']),
        ]


class Warehouse(models.Model): 
    '''定义维护物料仓库'''
    id = models.SmallAutoField(primary_key=True)
    warehouse = models.CharField(max_length=30, verbose_name='仓库名称')
    department = models.ForeignKey(Department, on_delete=models.PROTECT, verbose_name='归属县区')
    company = models.ForeignKey(Company, on_delete=models.PROTECT, verbose_name='所属地市')
    is_deleted = models.BooleanField(default=False, verbose_name='是否删除')
      
    def __str__(self):
        return self.warehouse
    class Meta:
        verbose_name = '维护仓库清单'
        verbose_name_plural = '维护仓库清单'
        ordering = ['-id']

   
class Materialtype(models.Model): 
    '''定义维护物料的类别，便于后续物料的管理'''
    id = models.SmallAutoField(primary_key=True)
    materialtype = models.CharField(max_length=30, blank=False, verbose_name='物料类别')
    company = models.ForeignKey(Company, on_delete=models.PROTECT, verbose_name='所属地市')
    is_deleted = models.BooleanField(default=False, verbose_name='是否删除')

    def __str__(self):
        return self.materialtype
    class Meta:
        verbose_name = '维护物料类别'
        verbose_name_plural = '维护物料类别'
        ordering = ['-id']
    

class Material(models.Model): 
    '''定义库存需要管理的维护物料清单，域内统一使用同一份物料清单'''
    id = models.AutoField(primary_key=True)
    material = models.CharField(max_length=30, verbose_name='物料名称')
    specification = models.CharField(max_length=30, verbose_name='规格型号')
    measureunit = models.CharField(max_length=10, verbose_name='计量单位')
    materialtype = models.ForeignKey(Materialtype, on_delete=models.PROTECT, verbose_name='物料类别')
    company = models.ForeignKey(Company, on_delete=models.PROTECT, verbose_name='所属地市')
    is_deleted = models.BooleanField(default=False, verbose_name='是否删除')

    def __str__(self):
        return self.material
    class Meta:
        verbose_name = '维护物料清单'
        verbose_name_plural = '维护物料清单'
        ordering = ['-id']
        indexes = [
            models.Index(fields=['materialtype']),
            models.Index(fields=['company']), 
        ]


class Inventory(models.Model): 
    '''定义库存物资表'''
    id = models.AutoField(primary_key=True)
    material = models.ForeignKey(Material, on_delete=models.PROTECT, verbose_name='物料名称')
    warehouse = models.ForeignKey(Warehouse, on_delete=models.PROTECT, verbose_name='仓库名称')
    quantity = models.IntegerField(verbose_name='库存数量')
    department = models.ForeignKey(Department, on_delete=models.PROTECT, verbose_name='归属县区')
    company = models.ForeignKey(Company, on_delete=models.PROTECT, verbose_name='所属地市')

    class Meta:
        unique_together = ('material', 'warehouse')
    def __str__(self):
        return self.material.material
    class Meta:
        verbose_name = '维护库存物资'
        verbose_name_plural = '维护库存物资'
        ordering = ['-id']
        indexes = [
            models.Index(fields=['warehouse']),
            models.Index(fields=['department']),
            models.Index(fields=['company']), 
        ]

   
class InventoryRecord(models.Model): 
    MODE_CHOICES = (
        ('in_stock', '存量入库'),
        ('purchase', '采购入库'),
        ('return', '维护返料'),
        ('transfer_in', '库间调入'),
        ('project_in', '项目余料入库'),
        ('donation_in', '捐赠入库'),
        ('adjustment_in', '盘盈入库'),
        ('maintain', '维护出库'),
        ('write_off', '损失核销'),
        ('transfer_out', '库间调出'),
        ('project_out', '项目领用'),
        ('expired_out', '过期报废'),
        ('damage_out', '损坏报废'),
        ('adjustment_out', '盘亏出库'),
    )
    STATUS_CHOICES = (
    ('pending', '待审批'),
    ('approved', '批准'),
    ('rejected', '拒绝'),
    )
    id = models.AutoField(primary_key=True)
    inventory = models.ForeignKey(Inventory, null=True, on_delete=models.PROTECT, verbose_name='库存记录')  # 修改为Inventory外键
    quantity = models.IntegerField(verbose_name='出入库数量')
    quantity_before = models.IntegerField(verbose_name='出入库前数量', null=True, blank=True)
    quantity_after = models.IntegerField(verbose_name='出入库后数量', null=True, blank=True)
    operatedate = models.DateField(verbose_name='申请日期')
    reason = models.CharField(max_length=50, verbose_name='出入库原因')
    operatemode = models.CharField(max_length=20, choices=MODE_CHOICES, verbose_name='出入库方式')
    approvalstatus = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending', verbose_name='审批状态')
    operator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, related_name='inventory_operator_logs', null=True, verbose_name='操作人')
    approver = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, related_name='inventory_approver_logs', null=True, verbose_name='审批人')
    approval_date = models.DateTimeField(null=True, blank=True, verbose_name='审批日期')
    approval_opinion = models.CharField(max_length=100, default='同意', verbose_name='审批意见')
    department = models.ForeignKey(Department, on_delete=models.PROTECT, verbose_name='归属县区')
    company = models.ForeignKey(Company, on_delete=models.PROTECT, verbose_name='所属地市')

    def __str__(self):
        return Inventory.objects.get(id=self.inventory_id).material.material

    class Meta:
        verbose_name = '维护物料出入库记录'
        verbose_name_plural = '维护物料出入库记录'
        ordering = ['-id']
        indexes = [
            models.Index(fields=['approvalstatus']),
            models.Index(fields=['department']),
            models.Index(fields=['company']), 
        ]



